#include "audio.h"

//==============================================================================MAIN INTERFACE
pthread_t audio_init()
{	
	pthread_t thread_id = 0;
	
	int r = pthread_create( &thread_id, NULL, audio_thread, NULL );
	assert( !r  );

	return thread_id;
}


//------------------------------------------------------------------------------COMMAND INTERFACE
void audio_exit()
{
	pthread_mutex_lock( &audio_command_mutex );
	audio_command.type = C_EXIT;	
	pthread_mutex_unlock( &audio_command_mutex );
}

void audio_playback( bool relative_on, int list_offset, int file_offset )
{	
	pthread_mutex_lock( &audio_command_mutex );
	audio_command.type = C_PLAYBACK;
	audio_command.playback.relative_on = relative_on;
	audio_command.playback.list_offset = list_offset;
	audio_command.playback.file_offset = file_offset;		
	pthread_mutex_unlock( &audio_command_mutex );
}

void audio_pause()
{
	pthread_mutex_lock( &audio_command_mutex );
	audio_command.type = C_PAUSE;		
	pthread_mutex_unlock( &audio_command_mutex );
}

void audio_stop()
{
	pthread_mutex_lock( &audio_command_mutex );
	audio_command.type = C_STOP;
	pthread_mutex_unlock( &audio_command_mutex );
}

void audio_volume( bool relative_on, int volume_offset, bool mute_on )
{
	if( volume_offset < 0 && volume_offset > 999 ) return;
	
	pthread_mutex_lock( &audio_command_mutex );
	audio_command.type = C_VOLUME;
	audio_command.volume.relative_on = relative_on;
	audio_command.volume.volume_offset = volume_offset;
	audio_command.volume.mute_on = mute_on;		
	pthread_mutex_unlock( &audio_command_mutex );
}

void audio_seek( bool relative_on, int seek_offset )
{
	if( seek_offset < 0 && seek_offset > 999 ) return;
	
	pthread_mutex_lock( &audio_command_mutex );
	audio_command.type = C_SEEK;
	audio_command.seek.relative_on = relative_on;
	audio_command.seek.seek_offset = seek_offset;
	pthread_mutex_unlock( &audio_command_mutex );
}

void list_add( char *dir, char *list_name )
{
	if( !dir || !list_name ) return;

	char *_dir = (char *)malloc( strlen(dir)+1 );
	strcpy( _dir, dir );
	char *_list_name = (char *)malloc( strlen(list_name)+1 );
	strcpy( _list_name, list_name );	
	
	pthread_mutex_lock( &audio_command_mutex );
	audio_command.type = C_LIST_ADD;
	audio_command.list_add.dir_name = _dir;
	audio_command.list_add.list_name = _list_name;
	pthread_mutex_unlock( &audio_command_mutex );
}

void list_del( int offset )
{
	pthread_mutex_lock( &audio_command_mutex );
	audio_command.type = C_LIST_DEL;
	audio_command.list_del.offset = offset;
	pthread_mutex_unlock( &audio_command_mutex );
}

void list_clear_status()
{
	pthread_mutex_lock( &audio_command_mutex );
	audio_command.type = C_LIST_CLEAR_STATUS;
	pthread_mutex_unlock( &audio_command_mutex );
}

void change_output( char *name )
{
	char *_name = (char *)malloc( strlen(name)+1 );
	strcpy( _name, name );
	
	pthread_mutex_lock( &audio_command_mutex );
	audio_command.type = C_CHANGE_OUTPUT;
	audio_command.change_output.name = _name;	
	pthread_mutex_unlock( &audio_command_mutex );
}

//------------------------------------------------------------------------------DATA INTERFACE
char * ENTRY_name( entry_s *ety )
{ return ety->name; }

char * ENTRY_file_name( entry_s *ety )
{ return ety->file_name; }

int ENTRY_size( entry_s *ety )
{ return ety->size; }

format_e ENTRY_format( entry_s *ety )
{ return ety->format; }

long ENTRY_bit_rate( entry_s *ety )
{ return ety->bit_rate; }

long ENTRY_duration( entry_s *ety )
{ return ety->duration; }

int ENTRY_channels( entry_s *ety )
{ return ety->channels; }

int ENTRY_channel_layout( entry_s *ety )
{ return ety->channel_layout; }

int ENTRY_sample_rate( entry_s *ety )
{ return ety->sample_rate; }

sample_format_e ENTRY_sample_format( entry_s *ety )
{ return ety->sample_format; }

char * ENTRY_title( entry_s *ety )
{ return ety->title; }

char * ENTRY_artist( entry_s *ety )
{ return ety->artist; }

char * ENTRY_album( entry_s *ety )
{ return ety->album; }

//------------------------------------------------------------------------------
int LIST_end_list()
{ return end_list; }

int LIST_cur_list()
{ return cur_list; }

char * LIST_dir_name( unsigned int l_off )
{ return list[l_off].dir_name; }

char * LIST_list_name( unsigned int l_off )
{ return list[l_off].list_name; }

unsigned int LIST_cur_entry( unsigned int l_off )
{ return list[l_off].cur_entry; }

struct entry * LIST_entry_array( unsigned int l_off, unsigned int e_off )
{ return (list[l_off].entry_array)[ e_off ]; }

unsigned int LIST_total_entries_number( unsigned int l_off )
{ return list[l_off].total_entries_number; }

unsigned int LIST_sequence( unsigned int l_off, unsigned int e_off )
{ return (list[l_off].sequence)[ e_off ]; }

//------------------------------------------------------------------------------
int STATUS_flags( const char *status_mask )
{
	if( ! strcmp(status_mask, "PLAYING") ){
		return status.flags & PLAYING;
	}
	if( ! strcmp(status_mask, "STOPPED") ){
		return status.flags & STOPPED;
	}
	if( ! strcmp(status_mask, "PAUSED") ){
		return status.flags & PAUSED;
	}
	if( ! strcmp(status_mask, "EOS") ){
		return status.flags & EOS;
	}
	if( ! strcmp(status_mask, "ERROR") ){
		return status.flags & ERROR;
	}
	
	if( ! strcmp(status_mask, "ADDING") ){
		return status.flags & ADDING;
	}
	if( ! strcmp(status_mask, "DELING") ){
		return status.flags & DELING;
	}
	if( ! strcmp(status_mask, "COMPLETED") ){
		return status.flags & COMPLETED;
	}

	return 0;
}

entry_s * STATUS_now_playing()
{ return status.now_playing; }

int STATUS_volume()
{ return status.volume; }

bool STATUS_mute_on()
{ return status.mute_on; }

int STATUS_position()
{ return status.position; }

entry_s * STATUS_now_adding()
{ return status.now_adding; }

entry_s * STATUS_now_deling()
{ return status.now_deling; }

//------------------------------------------------------------------------------
char * OUTPUT_lib( int offset )
{ return context.libs_output[offset]; }

char * OUTPUT_lib_using()
{ return output_using; }


